<!--
  input公共组件                 zls-2022/05/28
      Attributes
          1、label              左侧内容
          其他所有属性均参考vant组件库中的  "Uploader 文件上传"

      Events

      Demo==>
          参考 Form 表单组件
-->
<template>
  <div class="z-uploader">
    <div class="z-uploader-label">
      <span class="z-uploader-label-required">{{ formItem.isRequired ? '*' : '' }}</span>
      <span class="z-uploader-label-title">{{ label }}</span>
    </div>
    <div class="z-uploader-content">
      <Uploader
        v-model="fileList.list"
        :accept="$attrs['accept'] || '*'"
        :name="$attrs['name']"
        :preview-size="$attrs['preview-size'] || pxToRem(78)"
        :preview-image="$attrs['preview-image']"
        :preview-full-image="$attrs['preview-full-image']"
        :preview-options="$attrs['preview-options']"
        :multiple="$attrs['multiple']"
        :disabled="$attrs['disabled']"
        :readonly="$attrs['readonly']"
        :deletable="$attrs['deletable']"
        :show-upload="$attrs['show-upload']"
        :capture="$attrs['capture']"
        :max-size="$attrs['max-size']"
        :max-count="$attrs['max-count']"
        :result-type="$attrs['result-type']"
        :upload-text="$attrs['upload-text']"
        :image-fit="$attrs['image-fit']"
        :upload-icon="$attrs['upload-icon']"
        :before-read="$attrs['before-read']"
        :after-read="$attrs['after-read']"
        :before-delete="deleteFile"
        @click-preview="clickPreview"
      >
        <template #preview-cover="{ name, type }">
          <img v-if="type !== 'image'" class="preview-cover" :src="fileTypeObj[type]" alt="" />
          <div v-if="name" class="preview-tip">{{ name }}</div>
        </template>
      </Uploader>
      <div class="z-uploader-content-tips" v-if="formItem.validateState">{{ formItem.validateMessage }}</div>
    </div>
  </div>
</template>

<script>
export default { name: 'z-uploader' }
</script>
<script setup>
import { useAttrs, inject, getCurrentInstance, watch, reactive } from 'vue'
import { Uploader, Dialog, Notify } from 'vant'
import { pxToRem } from '@/utils'
import word from '@img/uploader/word.png'
import excel from '@img/uploader/excel.png'
import ppt from '@img/uploader/ppt.png'
import txt from '@img/uploader/txt.png'
import pdf from '@img/uploader/pdf.png'
import zip from '@img/uploader/zip.png'
import audio from '@img/uploader/audio.png'
import video from '@img/uploader/video.png'
// 根据文件类型，设置对应的图片
const fileTypeObj = { word, excel, ppt, txt, pdf, zip, audio, video }

const attrs = useAttrs()
const global = getCurrentInstance().appContext.config.globalProperties
const formItem = inject('formItem')
const emit = defineEmits(['delete', 'update:modelValue'])
defineProps({
  // 左侧内容
  label: {
    type: String,
    default: '文件上传'
  }
})
const fileList = reactive({ list: [] }) // 文件列表，格式：[{url:'',type:'',name:''}]

watch(
  () => attrs.modelValue,
  newVal => {
    fileList.list = newVal ?? []
    global.$bus.emit('formItem-change')
  },
  { immediate: true, deep: true }
)

// 删除文件时触发（调用后台文件服务删除该文件）
function deleteFile(file, detail) {
  Dialog.confirm({ message: '确定删除该文件吗?' })
    .then(() => {
      setTimeout(() => {
        fileList.list.splice(detail.index, 1)
        emit('update:modelValue', fileList.list)
        Notify({ type: 'success', message: '删除成功' })
        global.$bus.emit('formItem-change')
      }, 1000)
    })
    .catch(() => {})
}

// 点击文件直接打开（除image图片外）
function clickPreview(file) {
  console.log('--打开文件--', file)
  if (file.type === 'image') return
  window.open(file.url)
}
</script>

<style scoped lang="scss">
$warnColor: #ee0a24;
.z-uploader {
  display: flex;
  flex-direction: column;
  padding: 10px 0;
  line-height: 20px;
  font-size: 14px;
  &-label {
    display: flex;
    margin-bottom: 10px;
    &-required {
      color: $warnColor;
      width: 6px;
    }
  }
  &-content {
    flex: 1;
    display: flex;
    flex-direction: column;

    &-tips {
      font-size: 12px;
      color: $warnColor;
      padding-left: 2px;
    }
  }

  .preview-cover {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  .preview-tip {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 24px;
    line-height: 24px;
    padding: 0 2px;
    color: #fff;
    font-size: 12px;
    text-align: center;
    background: rgba(0, 0, 0, 0.4);
    @include oflow();
  }
}
</style>
